Skip to content

Recover a join predicate for a polymorphic reference #845

Description

@ddeboer

Summary

A polymorphic reference – a lookup naming more than one target, as #717 delivers – can never be joinable: a Typesense reference field names one target collection, and ids that live in two collections have no single collection to reference. So a join predicate on such a reference is out of reach: a filter evaluated on the referent’s own document rather than on the referring one, such as “works whose creator died before 1900” or “whose creator is located in Maastricht”.

#717 delivers everything else – labels, per-type output fields, __typename, id filters and facet buckets all work from the referring document plus the batched lookup. This issue holds the one capability it leaves out.

Three ways to recover it

Set out in #717; repeated here so the trade-off stays in one place.

  • A. A shared collection of the common fields. An agents collection carrying what Person and Organization share, reached by a single-target reference. The intersection is essentially label, so this restores a join over precisely what the lookup already gives and leaves per-type filters unreachable. Fixes the mechanism, recovers no functionality.
  • B. The same collection denormalised to the union of fields. agents carries birthDate and location, each absent for the kind it does not apply to, plus a discriminator. Joins work over per-type fields; the resolver reads the discriminator and returns the matching per-target type with only the fields that apply. Asks least of the engine. Costs: a second copy of every agent in RAM, two copies to keep in step (a second provenance stamp, inheriting Single-valued provenance stamp: shared entities lose sources and can be swept while still contributed #697 in a second place), sparsity rules for sort_by and for a filter that only one type can satisfy, a defined answer for a node co-typed with two merged classes, a rule for field-name collisions, and a rebuild whenever the merged set changes.
  • C. One reference field per target, disjoined at query time. creator → persons.id and creator → organizations.id; each document resolves in one and dangles in the other, and the predicate compiles to $persons(…) || $organizations(…). No new collection and per-type fields survive. Rests on two behaviours to verify against Typesense first: whether a permanently dangling async_reference is tolerated, and whether two joinable fields on one root type pointing at different collections coexist – ADR 19’s one-edge rule is keyed per target collection, so the second looks safe, but was not measured.

Not now

No deployment has asked for a filter on a referent’s own properties through a polymorphic reference. Until one does, a multi-target lookup refuses joinable at schema validation, as inline and local already do, and ADR 27 points here.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions