Family references discriminate through the referenced row's type (+ GUC empty-string guards) #2
Reference in New Issue
Block a user
No description provided.
Delete Branch "family-discriminates-through-the-reference"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Intention
Make local
<prop>_typecolumns optional denormalization instead of an engine requirement, so schemas can reference a party/entity by id alone. Came out of the payer/payee work onagreego/api(satya): invoicepayer_id/ billpayee_idshould be the whole reference — the discriminator is derivable, and today we keep columns + domains + FKs + a stamping trigger purely to feed the queryer.What changed
compile_one_of(queryer): a type-strategy family REFERENCE (payer,source,target…) now picks its polymorphic branch through the referenced row's own type:instead of
CASE WHEN parent.<prop>_type = 'person' THEN …. The truth, not a local cache — and the local_typecolumn stops being required. Untouched:kind-strategy STI and a row's self-discrimination (no referenced row to consult); those still read locally. All CASEs are emitted in simple form so the operand — even as a subquery — is evaluated once.Cost: one indexed lookup into
agreego.entityper hydrated reference, on the hottest, best-cached table in the system.Existing
_typecolumns keep working (they're just no longer read by hydration). On the api side we'd then droppayer_type/payee_type+ their domains/FKs/trigger at leisure;relationship.source_type/target_typecan stay as deliberate denormalization for the SQL that reads them directly.GUC readers (pgrx executor):
auth.user_idandpunc.externalnowNULLIF(…, '')before their COALESCE fallback. A rolled-back transaction that first-sets a custom GUC leaves it as an empty string session-wide (Postgres quirk — not unset), so the fallback never fired and the poisoned pooled connection wrote NULLcreated_byon every later merge. Same guardagreego.get_cue()already has. (We hit this live: the first server-sideset_config('auth.user_id', …)in a rolled-back test poisoned its pool connection; reproduced in raw psql.)Verification
cargo test: 1286 green. Golden queryer fixtures regenerated viaUPDATE_EXPECT— the diff is exactly the two shapes above, no other drift.🤖 Generated with Claude Code
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.