Compare commits

...

6 Commits

Author SHA1 Message Date
10e388421d version: 1.0.162 2026-06-19 15:35:01 -04:00
7f666e0ece Revert "queryer: NULL-tolerant bound for optional single-family forward relations"
This reverts commit 94477b677d.
2026-06-19 15:34:24 -04:00
98a9719509 Revert "queryer: don't emit a parent type-bound for reified-relationship properties"
This reverts commit c97e5d75b3.
2026-06-19 15:34:23 -04:00
0509995589 version: 1.0.161 2026-06-19 11:08:52 -04:00
c97e5d75b3 queryer: don't emit a parent type-bound for reified-relationship properties
A SINGLE reified-relationship property (e.g. invoice.counterparty,
person.primary_contact — a property whose type is a relationship
subtype) is hydrated by a correlated subquery that joins the
relationship table and correlates source_id/target_id = parent.id; its
discriminators (the relationship subtype and the target's type CASE)
are constrained INSIDE that subquery.

For such a property the resolved edge is a REVERSE traversal
(forward = false) over a generic relationship FK
(fk_relationship_source_entity, destination = entity). compile_
polymorphic_bounds then took the `!edge.forward` branch with
poly_col = destination_columns[1] = "type" and
table_to_alias = "entity", which resolves to the PARENT's entity alias
— emitting a bound like `entity_1.type = 'counterparty'` into the
parent WHERE. No parent row has that type, so EVERY parent was dropped
(e.g. get_invoice returned null for an existing invoice whose
counterparty edge was absent).

Array reified traversals (contacts, occupancies) never hit this: an
array property has no bound_type_name. Only the single form did, and it
was previously unexercised.

Fix: in compile_polymorphic_bounds, skip the bound when the property's
resolved type is itself a relationship (type_def.relationship) — there
is no parent-row discriminator column to bound.

Test: new queryer case (person.primary_contact, type=contact) asserts
the parent WHERE has no spurious entity.type bound while the subquery
keeps its discriminator + source_id correlation. Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:03:13 -04:00
94477b677d queryer: NULL-tolerant bound for optional single-family forward relations
An OPTIONAL forward polymorphic relation declared via `family` (e.g.
order.counterparty / invoice.counterparty) had its auto-generated type
bound `{alias}.{disc} IN (variations)` emitted into the PARENT row's
WHERE. When the relation is absent (NULL discriminator) the parent row
was wrongly excluded — a counterparty-less order/invoice returned
nothing instead of the row with `counterparty: null`.

Fix: in `compile_polymorphic_bounds`, make the forward-FK bound
NULL-tolerant (`(… IN (…) OR …_type IS NULL)`), gated on
`!r#type.relationship`:
  - real entities get NULL-tolerance (the relation is an optional
    attribute; an absent one must not drop the row — the inner CASE
    already resolves it to NULL);
  - edge entities (`relationship == true`, e.g. `contact`) keep the
    bound EXACT, because there source_type/target_type *partition*
    typed sub-collections (phone_numbers vs email_addresses) and a NULL
    endpoint belongs to no partition.

Note: the `oneOf` path was already correct — it emits no parent bound
(resolves via CASE … ELSE NULL), so cross-family optional relations
already hydrate NULL-safely. Added a fixture case documenting that.

Tests (fixtures/queryer.json): case 15 (entity → NULL-tolerant),
cases 3/5/10 (contact edges → exact, unchanged), new case 16
(oneOf cross-family → no bound). Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 10:22:29 -04:00

View File

@ -1 +1 @@
1.0.160
1.0.162