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

Validates that root `where` predicates can all be satisfied.

This catches impossible filters.

## Examples

Bad:

    from(Post, as: :post)
    |> where([post: p], p.status == ^:draft)
    |> where([post: p], p.status == ^:published)

Why this is bad:

No row can satisfy both equality predicates for the same field. The query is
guaranteed to return no rows, which usually means a filter was composed
incorrectly.

Better:

    from(Post, as: :post)
    |> where([post: p], p.status in ^[:draft, :published])

Why this is better:

The allowed values are represented in one satisfiable predicate.

Bad:

    from(Post, as: :post)
    |> where([post: p], p.sequence == ^1)
    |> where([post: p], p.sequence == ^2)

## Notes

This check is intentionally narrow. It evaluates supported root `where`
predicates and ignores fragments, subqueries, non-root bindings, and most
arbitrary expressions.

The check is intentionally narrow. It evaluates root schema fields and only
trusts direct `==`, `in`, and `is_nil` predicates in `AND` where expressions.
`Ecto.Enum` fields are normalized through the schema enum mapping. Non-enum
fields only compare simple literal values that already match the schema field
type. `or_where` and `or` expressions are handled as separate branches and
only rejected when every branch is statically unsatisfiable and at least one
branch has a true predicate conflict. Fragments, subqueries, and non-root
bindings are ignored. Empty `in` candidate lists can make a branch
unsatisfiable, but standalone empty `in` issues are intentionally left to
`Bylaw.Ecto.Query.Checks.EmptyInPredicates`.

## 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*
