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

Copy Markdown View Source

Validates that queries do not use explicit cartesian joins.

This check catches join shapes that are easy to introduce accidentally and expensive to run.

Examples

Bad:

from(Post, as: :post)
|> join(:inner, [post: p], c in Comment,
  as: :comment,
  on: true
)

Why this is bad:

on: true creates every possible pair of posts and comments. That can multiply rows, inflate aggregates, and produce a query that is much more expensive than intended.

Better:

from(Post, as: :post)
|> join(:inner, [post: p], c in Comment,
  as: :comment,
  on: c.post_id == p.id
)

Why this is better:

The join predicate states the relationship between the two tables, so each joined row is tied back to its post.

Bad:

from(Plan, as: :plan)
|> join(:cross, [plan: pl], f in Feature, as: :feature)
|> where([feature: f], f.enabled == true)

Notes

This check catches obvious cartesian joins: cross_join, uncorrelated cross_lateral_join, and non-association joins whose on expression is literally true. It does not parse SQL fragments or prove general SQL cardinality.

It rejects cross_join, uncorrelated cross_lateral_join, and non-association joins whose on expression is literally true. Correlated lateral joins are treated as constrained when a supported subquery predicate depends on both a local subquery binding and a previous parent binding, or when a lateral fragment source exposes a previous parent binding reference.

Options

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

Like Bylaw's other Ecto query checks, this intentionally inspects the query structure produced by Ecto's query macros. It supports the tested join and lateral subquery shapes exposed by the Ecto query API. Association joins are not considered literal on: true joins because Ecto stores their association predicate separately from the on expression.

This check is a guardrail for obvious cartesian joins, not a full SQL cardinality proof. It does not parse fragment SQL. For lateral fragments, an Ecto-visible reference to a previous binding is treated as dependency evidence; opaque SQL that needs stricter review should be handled in the application query or by disabling the check for that call site.

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.