Skip to content

feat(analysis): accept any boolean expression as a join ON condition - #72

Merged
omer-cengel merged 1 commit into
masterfrom
feature/join-conditions-of-any-boolean-expression
Oct 11, 2026
Merged

omer-cengel merged 1 commit into
masterfrom
feature/join-conditions-of-any-boolean-expression

Conversation

@omer-cengel

Copy link
Copy Markdown
Member

Summary

A join's ON condition was limited to one qualified equality between the joined source and an earlier one. Common queries such as composite-key joins, filtered left joins and ON TRUE were therefore rejected. An inner or left join may now carry any boolean expression in its ON condition, and its placeholders are typed the same way as in WHERE.

Changes

  • Each inner or left join accepts exactly one ON condition of any boolean expression, including composite keys, comparisons other than equality, conditions over one source, unqualified columns and ON TRUE.
  • Every column reference in the condition, outside a nested SELECT, resolves against the sources introduced up to and including the joined source. A reference to a later source fails as an unknown source qualifier, and an unknown column fails as before.
  • Placeholders in the condition are typed by the WHERE predicate rules, in both placeholder forms. Cast placeholders state their own type. Every placeholder binds in textual order, so an ON placeholder binds before a WHERE one.
  • A join without ON, and the nested JOIN a JOIN b ON x ON y form, are rejected with A join requires one ON condition.
  • Columns of a left-joined source stay nullable regardless of what the condition filters.
  • Query documentation describes the join rules, the new rejection and the added tests.
  • Analyzer tests, a generated-repository compilation test, and a PostgreSQL test cover the change. The PostgreSQL test runs a filtered left join over matched, filtered-out and unmatched rows.

Scope and non-goals

  • The accepted join kinds are unchanged. RIGHT, FULL, CROSS, USING, NATURAL, comma-separated and LATERAL joins keep their current rejection.
  • A nested SELECT inside ON is not analyzed, apart from cast placeholders.
  • An uncast placeholder that the WHERE rules cannot type, such as lower(p.nickname) = :n, keeps its existing rejection.
  • Conflict clauses, RETURNING and the rest of WHERE analysis are unchanged.

A join's ON condition is no longer limited to one qualified equality.
Composite-key joins, filtered joins, comparisons other than equality and
ON TRUE compile. Every column of the condition outside a nested SELECT
resolves against the sources introduced up to and including the joined
source. Its placeholders are typed by the WHERE rules and bind in textual
order. A join without ON, or with two ON conditions, is rejected with
"A join requires one ON condition."

Left-joined columns stay nullable whatever the condition filters.
@omer-cengel
omer-cengel merged commit 2366ff5 into master Oct 11, 2026
7 checks passed
@omer-cengel
omer-cengel deleted the feature/join-conditions-of-any-boolean-expression branch October 11, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant