Compare commits

..

8 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
fb25224d22 version: 1.0.160 2026-06-18 20:31:49 -04:00
01368305de fixed missing schema ids in validation results 2026-06-18 20:31:35 -04:00
3 changed files with 12 additions and 6 deletions

View File

@ -251,12 +251,18 @@ fn test_library_api() {
{
"code": "REQUIRED_FIELD_MISSING",
"message": "Missing name",
"details": { "path": "name" }
"details": {
"path": "name",
"schema": "source_schema"
}
},
{
"code": "STRICT_PROPERTY_VIOLATION",
"message": "Unexpected property 'wrong'",
"details": { "path": "wrong" }
"details": {
"path": "wrong",
"schema": "source_schema"
}
}
]
})

View File

@ -69,7 +69,7 @@ impl Validator {
path: Some(e.path),
cause: None,
context: None,
schema: None,
schema: Some(schema_id.to_string()),
},
})
.collect();
@ -83,7 +83,7 @@ impl Validator {
path: Some(e.path),
cause: None,
context: None,
schema: None,
schema: Some(schema_id.to_string()),
},
}]),
}
@ -95,7 +95,7 @@ impl Validator {
path: Some("/".to_string()),
cause: None,
context: None,
schema: None,
schema: Some(schema_id.to_string()),
},
}])
}

View File

@ -1 +1 @@
1.0.159
1.0.162